package net.lcheng.sellerCenter.utils;

import net.lcheng.commons.utils.ParseMD5;
import net.lcheng.model.*;
import net.lcheng.service.*;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.codehaus.plexus.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * 管理员权限认证类
 *
 * @version 1.0
 */
public class ShiroRealm extends AuthorizingRealm {


    private static final Logger log = Logger.getLogger(ShiroRealm.class);

    @Autowired
//    private SysUsersService userService;
    private UserService userService;
    @Autowired
    private SysUserRolesService userRoleService;
    @Autowired
    private SysRolePermissionsService sysRolePermissionsService;
    @Autowired
    private SysPermissionsService sysPermissionsService;

    /**
     * 为当前登录的Subject授予角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {


        // 获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next()
        String currentUsername = (String) super.getAvailablePrincipal(principals);
        List<String> roleList = new ArrayList<String>();
        List<String> permissionList = new ArrayList<String>();
        // 从数据库中获取当前登录用户的详细信息
//        roleList.add("admin");

//        SysUsers user = userService.getUserByUsername(currentUsername);
        User user =userService.getUserByPhone(currentUsername);
        if(null != user){
            //超级用户直接获取所有权限
            //if(user.getIsAdministrator()==1){
                List<SysPermissions> pList = sysPermissionsService.getAll();
                if(pList!=null && pList.size()>0){
                    for (SysPermissions p: pList) {
                        permissionList.add(p.getPermissionKey());
                    }
                //}
            }else {
                //获取用户角色列表
                List<SysUserRoles> roles = userRoleService.getUserRolesByUserName(currentUsername);
                List<Integer> roleIdList = new ArrayList<>();
                if (roles != null&&roles.size()>0) {
                    for (SysUserRoles role : roles) {
                        System.out.println(role.getRoleKey());
                        log.debug("授予角色>>>" + role.getRoleKey());
                        roleList.add(role.getRoleKey());
                        roleIdList.add(role.getRoleId());
                    }
                }
                //获取用户权限列表
                List<SysRolePermissions> permissionsList = sysRolePermissionsService.getPermissionsByRoleIds(roleIdList);
                if (permissionsList != null && permissionsList.size() > 0) {
                    for (SysRolePermissions pmss : permissionsList) {
                        if (!StringUtils.isBlank(pmss.getPermissionKey())) {
                            log.debug("授予权限>>>>" + pmss.getPermissionKey());
                            permissionList.add(pmss.getPermissionKey());
                        }
                    }
                }
            }

        }else {
            throw new AuthorizationException();
        }

//        if (null != user) {
//            // 实体类User中包含有用户角色的实体类信息
//            if (null != user.getRoles() && user.getRoles().size() > 0) {
//                // 获取当前登录用户的角色
//                for (Role role : user.getRoles()) {
//                    if (!StringUtils.isBlank(role.getName())) {
//                        log.debug("授予角色>>>" + role.getName());
//                        roleList.add(role.getName());
//                    }
//                }
//            }
//            // 实体类User中包含有角色权限的实体类信息
//            if (null != user.getPermissions() && user.getPermissions().size() > 0) {
//                for (Permission pmss : user.getPermissions()) {
//                    if (!StringUtils.isBlank(pmss.getPermission())) {
//                        log.debug("授予权限>>>>" + pmss.getPermission());
//                        permissionList.add(pmss.getPermission());
//                    }
//                }
//            }
//        } else {
//            throw new AuthorizationException();
//        }
        // 为当前用户设置角色和权限
        SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
        simpleAuthorInfo.addRoles(roleList);
        simpleAuthorInfo.addStringPermissions(permissionList);


        return simpleAuthorInfo;
    }


    /**
     * 验证当前登录的Subject
     * 认证回调函数,登录时调用.
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        // 获取基于用户名和密码的令牌
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

//        SysUsers user = userService.getUserByUsername(token.getUsername());
        User user=userService.getUserByPhone(token.getUsername());

        AuthenticationInfo authcInfo = null;
        if (user == null) {
            throw new UnknownAccountException();// 未知账户
        }
        else if(!user.getUserPwd().equals(ParseMD5.parseStrToMd5L32(String.valueOf(token.getPassword())))){
            throw new UnknownAccountException();// 账户密码错误，与管理员联系
        }
//        else if (user.getStatus() == 0) {
//            throw new LockedAccountException();// 账户已锁定，与管理员联系
//        }
        else {
        authcInfo = new SimpleAuthenticationInfo(user.getUserPhone(),
                token.getPassword(),
                getName());

        this.setSession("currentUser", user.getUserPhone());
        }

        return authcInfo;
    }


    /**
     * 更新授权信息缓存
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * ShiroSession设置
     *
     * @see 使用时直接用HttpSession.getAttribute(key)就可以取到
     */
    private void setSession(Object key, Object value) {
        Subject currentUser = SecurityUtils.getSubject();
        if (null != currentUser) {
            Session session = currentUser.getSession();
            if (null != session) {
                session.setAttribute(key, value);
            }
        }
    }
}